import time

from tornado import gen
from tornado.httpclient import HTTPClient, AsyncHTTPClient
from tornado.ioloop import IOLoop


def count_time(func):
    def func_wrapper(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print("耗时{}秒".format(end - start))

    return func_wrapper


class AsyncIODemo:
    def synchronous_fetch(self, url):
        http_client = HTTPClient()
        response = http_client.fetch(url)
        return response.effective_url

    @gen.coroutine
    def async_gen_fetch(self, url):
        http_client = AsyncHTTPClient()
        response = yield http_client.fetch(url)
        raise gen.Return(response.effective_url)

    async def asynchronous_fetch(self, url):
        http_client = AsyncHTTPClient()
        response = await http_client.fetch(url)
        return response.effective_url

    async def minute_n_loop(self):
        while True:
            await print("minute_n loop")
            await gen.sleep(60)

    async def minute_loop(self):
        while True:
            nxt = gen.sleep(60)  # Start the clock.
            await print("minute loop")  # Run while the clock is ticking.
            await nxt  # Wait for the timer to run out.

    @count_time
    def _test_synchronous_fetch(self):
        """
        aid = AsyncIODemo()
        aid._test_synchronous_fetch()
        """
        for i in range(20):
            print(self.synchronous_fetch("https://www.baidu.com/"))

    @count_time
    def _test_async_gen_fetch(self):
        """
        aid = AsyncIODemo()
        aid._test_async_gen_fetch()
        """
        for i in range(20):
            print(self.async_gen_fetch("https://www.baidu.com/"))

    @count_time
    def _test_asynchronous_fetch(self):
        """
        aid = AsyncIODemo()
        aid._test_asynchronous_fetch()
        """
        for i in range(20):
            print(self.asynchronous_fetch("https://www.baidu.com/"))

    def _test_minute_n_loop(self):
        """
        aid = AsyncIODemo()
        aid._test_minute_n_loop()
        """
        IOLoop.current().spawn_callback(self.minute_n_loop)

    def _test_minute_loop(self):
        """
        aid = AsyncIODemo()
        aid._test_minute_loop()
        """
        IOLoop.current().spawn_callback(self.minute_loop)


if __name__ == '__main__':
    aid = AsyncIODemo()
    aid._test_minute_loop()
